home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 330_03 / tskwpip.c < prev   
C/C++ Source or Header  |  1990-10-10  |  7KB  |  283 lines

  1. /*
  2.    --- Version 2.2 90-10-12 11:08 ---
  3.  
  4.    TSKWPIP.C - CTask - Word Pipe handling routines.
  5.  
  6.    Public Domain Software written by
  7.       Thomas Wagner
  8.       Ferrari electronic Gmbh
  9.       Beusselstrasse 27
  10.       D-1000 Berlin 21
  11.       Germany
  12. */
  13.  
  14. #include "tsk.h"
  15. #include "tsklocal.h"
  16.  
  17.  
  18. /*
  19.    create_wpipe - initialises wpipe.
  20. */
  21.  
  22. wpipeptr Globalfunc create_wpipe (wpipeptr pip, farptr buf, word bufsize
  23.                                   TN(byteptr name))
  24. {
  25. #if (TSK_DYNAMIC)
  26.    if (pip == LNULL)
  27.       {
  28.       if ((pip = tsk_palloc (sizeof (wpipe))) == LNULL)
  29.          return LNULL;
  30.       pip->flags = F_TEMP;
  31.       }
  32.    else
  33.       pip->flags = 0;
  34.    if (buf == LNULL)
  35.       {
  36.       if ((buf = tsk_palloc (bufsize)) == LNULL)
  37.          {
  38.          if (pip->flags & F_TEMP)
  39.             tsk_pfree (pip);
  40.          return LNULL;
  41.          }
  42.       pip->flags |= F_STTEMP;
  43.       }
  44. #endif
  45.  
  46.    tsk_init_qhead (&pip->wait_read, TYP_WPIPE);
  47.    tsk_init_qhead (&pip->wait_write, TYP_WPIPE);
  48.    tsk_init_qhead (&pip->wait_clear, TYP_WPIPE);
  49.    pip->outptr = pip->inptr = pip->filled = 0;
  50.    pip->bufsize = bufsize >> 1;
  51.    pip->wcontents = (wordptr)buf;
  52.  
  53. #if (TSK_NAMED)
  54.    tsk_add_name (&pip->name, name, TYP_WPIPE, pip);
  55. #endif
  56.  
  57.    return pip;
  58. }
  59.  
  60.  
  61. /*
  62.    delete_wpipe - kills all processes waiting for reading from or writing
  63.                   to the wpipe.
  64. */
  65.  
  66. void Globalfunc delete_wpipe (wpipeptr pip)
  67. {
  68.    CRITICAL;
  69.  
  70.    CHECK_EVTPTR (pip, TYP_WPIPE, "Delete Wpipe");
  71.  
  72.    C_ENTER;
  73.    tsk_kill_queue (&(pip->wait_read));
  74.    tsk_kill_queue (&(pip->wait_write));
  75.    tsk_kill_queue (&(pip->wait_clear));
  76.    pip->outptr = pip->inptr = pip->filled = 0;
  77.    C_LEAVE;
  78.  
  79. #if (TSK_NAMED)
  80.    tsk_del_name (&pip->name);
  81. #endif
  82.  
  83. #if (TSK_DYNAMIC)
  84.    if (pip->flags & F_STTEMP)
  85.       tsk_pfree (pip->wcontents);
  86.    if (pip->flags & F_TEMP)
  87.       tsk_pfree (pip);
  88. #endif
  89. }
  90.  
  91.  
  92. /*
  93.    read_wpipe - Wait until a word is written to the wpipe. If there 
  94.                 is a word in the wpipe on entry, it is assigned to 
  95.                 the caller, and the task continues to run. If there are
  96.                 tasks waiting to write, the first task is made eligible,
  97.                 and the word is inserted into the wpipe.
  98. */
  99.  
  100. word Globalfunc read_wpipe (wpipeptr pip, dword timeout)
  101. {
  102.    tcbptr curr;
  103.    word res;
  104.    CRITICAL;
  105.  
  106.    CHECK_EVTPTR (pip, TYP_WPIPE, "Read Wpipe");
  107.  
  108.    C_ENTER;
  109.  
  110.    if (pip->filled)
  111.       {
  112.       res = pip->wcontents [pip->outptr++];
  113.       if (pip->outptr >= pip->bufsize)
  114.          pip->outptr = 0;
  115.       pip->filled--;
  116.  
  117.       if (!((curr = (tcbptr)pip->wait_write.first)->cqueue.kind & Q_HEAD))
  118.          {
  119.          pip->wcontents [pip->inptr++] = curr->retsize;
  120.          if (pip->inptr >= pip->bufsize)
  121.             pip->inptr = 0;
  122.          pip->filled++;
  123.          tsk_runable (curr);
  124.          curr->retptr = LNULL;
  125.          }
  126.       else if (!pip->filled)
  127.          tsk_runable_all (&pip->wait_clear);
  128.  
  129.       C_LEAVE;
  130.       return res;
  131.       }
  132.  
  133.    tsk_wait (&pip->wait_read, timeout);
  134.    return (int)((dword)GLOBDATA current_task->retptr);
  135. }
  136.  
  137.  
  138. /*
  139.    c_read_wpipe - If there is a word in the wpipe on entry,
  140.                   read_wpipe is called, otherwise an error status is returned.
  141. */
  142.  
  143. word Globalfunc c_read_wpipe (wpipeptr pip)
  144. {
  145.    CRITICAL, res;
  146.  
  147.    CHECK_EVTPTR (pip, TYP_WPIPE, "Cond Read Wpipe");
  148.  
  149.    C_ENTER;
  150.    res = (pip->filled) ? read_wpipe (pip, 0L) : (word)-1;
  151.    C_LEAVE;
  152.    return res;
  153. }
  154.  
  155.  
  156.  
  157. /*
  158.    write_wpipe - Wait until space for the word to be written to the 
  159.                  wpipe is available. If there is enough space in the wpipe 
  160.                  on entry, the word is inserted into the wpipe, and
  161.                  the task continues to run. If there are tasks waiting 
  162.                  to read, the first task is made eligible, and the word
  163.                  is passed to the waiting task.
  164. */
  165.  
  166. int Globalfunc write_wpipe (wpipeptr pip, word ch, dword timeout)
  167. {
  168.    tcbptr curr;
  169.    CRITICAL;
  170.  
  171.    CHECK_EVTPTR (pip, TYP_WPIPE, "Write Wpipe");
  172.  
  173.    C_ENTER;
  174.  
  175.    if (pip->filled < pip->bufsize)
  176.       {
  177.       if (!((curr = (tcbptr)pip->wait_read.first)->cqueue.kind & Q_HEAD))
  178.          {
  179.          tsk_runable (curr);
  180.          curr->retptr = (farptr)ch;
  181.          C_LEAVE;
  182.          return 0;
  183.          }
  184.  
  185.       pip->wcontents [pip->inptr++] = ch;
  186.       if (pip->inptr >= pip->bufsize)
  187.          pip->inptr = 0;
  188.       pip->filled++;
  189.       C_LEAVE;
  190.       return 0;
  191.       }
  192.  
  193.    GLOBDATA current_task->retsize = ch;
  194.    tsk_wait (&pip->wait_write, timeout);
  195.    return (int)((dword)GLOBDATA current_task->retptr);
  196. }
  197.  
  198.  
  199. /*
  200.    c_write_wpipe - If there is space for the word in the wpipe on entry,
  201.                    write_wpipe is called, otherwise an error status is returned.
  202. */
  203.  
  204. int Globalfunc c_write_wpipe (wpipeptr pip, word ch)
  205. {
  206.    int res;
  207.    CRITICAL;
  208.  
  209.    CHECK_EVTPTR (pip, TYP_WPIPE, "Cond Write Wpipe");
  210.  
  211.    C_ENTER;
  212.    res = (pip->filled < pip->bufsize) ? write_wpipe (pip, ch, 0L) : -1;
  213.    C_LEAVE;
  214.    return res;
  215. }
  216.  
  217.  
  218. /*
  219.    wait_wpipe_empty - Wait until the pipe is empty. If the pipe is
  220.                       empty on entry, the task continues to run.
  221. */
  222.  
  223. int Globalfunc wait_wpipe_empty (wpipeptr pip, dword timeout)
  224. {
  225.    CRITICAL;
  226.  
  227.    CHECK_EVTPTR (pip, TYP_WPIPE, "Wait Wpipe Empty");
  228.  
  229.    C_ENTER;
  230.    if (!pip->filled)
  231.       {
  232.       C_LEAVE;
  233.       return 0;
  234.       }
  235.  
  236.    GLOBDATA current_task->retptr = LNULL;
  237.    tsk_wait (&pip->wait_clear, timeout);
  238.    return (int)((dword)GLOBDATA current_task->retptr);
  239. }
  240.  
  241.  
  242. /*
  243.    check_wpipe - returns -1 if there are no words in the wpipe, else
  244.                  the first available word.
  245. */
  246.  
  247. word Globalfunc check_wpipe (wpipeptr pip)
  248. {
  249.    CHECK_EVTPTR (pip, TYP_WPIPE, "Check Wpipe");
  250.  
  251.    return (pip->filled) ? pip->wcontents [pip->outptr] : (word)-1;
  252. }
  253.  
  254.  
  255. /*
  256.    wpipe_free - returns the number of free words in the pipe.
  257. */
  258.  
  259. word Globalfunc wpipe_free (wpipeptr pip)
  260. {
  261.    CHECK_EVTPTR (pip, TYP_WPIPE, "Wpipe Free");
  262.    return pip->bufsize - pip->filled;
  263. }
  264.  
  265. /*
  266.    flush_wpipe - Empty the pipe buffer, activate tasks waiting for 
  267.                  pipe clear.
  268. */
  269.  
  270. void Globalfunc flush_wpipe (wpipeptr pip)
  271. {
  272.    CRITICAL;
  273.  
  274.    CHECK_EVTPTR (pip, TYP_WPIPE, "Flush Wpipe");
  275.    C_ENTER;
  276.    pip->inptr = pip->outptr = pip->filled = 0;
  277.  
  278.    tsk_runable_all (&pip->wait_clear);
  279.    C_LEAVE;
  280. }
  281.  
  282.  
  283.